<style>
    /* biz专属类*/
    #biz-copyright {
        position: absolute;
        bottom: 20px;
        width: 100%;
        font-size: smaller;
        text-align: center;
        line-height: 1.5em;
        color: #999;
    }

    .biz-logo {
        width: 200px;
        height: 60px;
        display: flex;
        align-items: center;
        justify-content: center;
    }

    .biz-logo-title {
        color: white;
        padding-bottom: 5px;
        font-weight: bold;
        font-size: 18px;
    }

    #biz-body {
        display: flex;
        flex-direction: column;
        padding-bottom: 0;
    }

    #biz-tab>#biz-tab-title {
        position: fixed;
        left: 250px;
        top: 50px;
        right: 0;
    }


    #biz-tab-title>*:first-child .layui-icon-close {
        display: none;
    }

    #biz-tab>#biz-tab-content>.layui-tab-item {
        position: fixed;
        top: 78px;
        right: 5px;
        left: 205px;
        bottom: 5px;
        background-color: white;
        padding: 10px;
        overflow-y: auto;
    }

    #biz-tab-index {
        min-width: 35px;
    }


    .biz-side-hide {
        display: none !important;
        transition: 0.5s;
    }

    .biz-header-mobile {
        left: 0 !important;
        transition: 0.5s;
    }

    .biz-body-mobile {
        left: 0 !important;
        transition: 0.5s;
    }

    .biz-tab-title-mobile {
        left: 0 !important;
        transition: 0.5s;
    }

    .biz-tab-content-mobile {
        left: 0 !important;
        transition: 0.5s;
    }

    .biz-tab-content-mobile .layui-tab-item {
        left: 5px !important;
        transition: 0.5s;
    }


    /*定制LayUI主题*/

    .layui-form-pane .layui-form-label {
        background-color: white;
    }

    .layui-btn,
    .layui-inline .layui-form-label,
    .layui-inline .layui-input-inline,
    table {
        zoom: 0.95;
    }

    .layui-layer.layui-layer-page,
    .layui-layer.layui-layer-dialog,
    .layui-layer.layui-layer-prompt,
    .layui-layer.layui-layer-iframe {
        border-radius: 2px;
    }

    .layui-layer.layui-layer-page .layui-layer-title,
    .layui-layer.layui-layer-prompt .layui-layer-title,
    .layui-layer.layui-layer-dialog .layui-layer-title,
    .layui-layer-iframe .layui-layer-title {
        height: 40px;
        font-size: 14px;
        line-height: 40px;
        border-radius: 2px 2px 0 0;
    }

    .layui-layer.layui-layer-page .layui-layer-setwin,
    .layui-layer.layui-layer-prompt .layui-layer-setwin,
    .layui-layer.layui-layer-dialog .layui-layer-setwin,
    .layui-layer.layui-layer-iframe .layui-layer-setwin {
        top: 9px;
    }

    .layui-layer.layui-layer-page .layui-layer-close1,
    .layui-layer.layui-layer-prompt .layui-layer-close1,
    .layui-layer.layui-layer-dialog .layui-layer-close1,
    .layui-layer.layui-layer-iframe .layui-layer-close1 {
        background: none !important;
        transition: 0.25s;

    }

    .layui-layer.layui-layer-page .layui-layer-close1:after,
    .layui-layer.layui-layer-prompt .layui-layer-close1:after,
    .layui-layer.layui-layer-dialog .layui-layer-close1:after,
    .layui-layer.layui-layer-iframe .layui-layer-close1::after {
        content: '×';
        font-size: 20px;
        color: black;
    }

    .layui-layer.layui-layer-iframe .layui-layer-close1:hover {
        transform: scale(1.1);
    }

    .layui-body>.layui-tab .layui-tab-item {
        padding: 0 !important;
    }

    .layui-form-item {
        line-height: 45px;
    }

    .layui-layout-admin>.layui-header {
        left: 200px;
    }

    .layui-layout-admin>.layui-side {
        top: 0;
    }

    .layui-layout-admin>.layui-header {
        height: 40px;
    }

    .layui-layout-admin>.layui-header .layui-nav-item {
        line-height: 40px;
    }

    .layui-side>.layui-side-scroll {
        width: 200px;
    }

    .layui-body {
        top: 30px !important;
        background-color: #F2F2F2;
    }

    .layui-tab-title {
        zoom: 0.8;
        z-index: 999999;
    }

    .layui-tab-title>li {
        height: 39px;
    }

    /*通用类*/
    .biz-flex-center-none {
        display: flex;
        align-items: center;
    }

    .biz-flex-center-center {
        display: flex;
        align-items: center;
        justify-content: center;
    }

    form.layui-form {
        padding: 10px;
        margin-top: 20px;
    }

    .layui-tab-title li {
        min-width: 30px;
    }

    #menu-other .layui-nav-child {
        top: 45px !important;
    }
</style>
<template>
    <div class="layui-layout layui-layout-admin">
        <div class="layui-header" id="biz-header">
            <ul class="layui-nav" id="biz-menu">
                <li class="layui-nav-item" id="biz-menu-dropdown">
                    <a href="javascript:;">
                        <i class="fa fa-th-list"></i>
                    </a>
                </li>
                <li class="layui-nav-item" style="cursor: pointer;">
                    <a lay-filter="showSide" data-show="1"><i class="layui-icon layui-icon-spread-left"></i></a>
                    <a lay-filter="showSide" data-show="0"><i class="layui-icon layui-icon-shrink-right"></i></a>
                </li>
                {{# layui.each(d.menus, function(idx, first_menu){ }}
                <li class="layui-nav-item">
                    <a lay-filter="switchModule" data-type="{{first_menu.type}}" data-index="{{idx}}"
                        data-url="{{first_menu.url||''}}">
                        <span><i class="{{first_menu.icon}}"></i></span>
                        <span>{{first_menu.title}}</span>
                    </a>
                </li>
                {{# }); }}
                <li class="layui-nav-item" id="menu-fold">
                    <a href="javascript:;">
                        <i class="layui-icon layui-icon-app"></i>
                    </a>
                    <dl class="layui-nav-child">
                        {{# layui.each(d.menus, function(idx, first_menu){ }}
                        <dd>
                            <a lay-filter="switchModule" data-index="{{idx}}" data-type="{{first_menu.type}}">
                                <i class="{{first_menu.icon}}"></i>
                                {{first_menu.title}}
                            </a>
                        </dd>
                        {{# }); }}
                    </dl>
                </li>

            </ul>

            <ul class="layui-nav layui-layout-right" id="menu-other">
                <li class="layui-nav-item">
                    <a href="javascript:;">
                        <i class="layui-icon layui-icon-layouts"></i>
                        主题
                    </a>
                    <dl class="layui-nav-child">
                        {{# layui.each(d.conf.view.theme.all, function(key, val){ }}
                        <dd><a lay-filter="updateTheme" data-theme="{{key}}">{{val}}</a></dd>
                        {{# }); }}
                    </dl>
                </li>
                <li class="layui-nav-item">
                    <a href="javascript:;">
                        <i class="layui-icon layui-icon-username"></i>
                        {{d.userNick}}
                    </a>
                    <dl class="layui-nav-child">
                        <dd><a lay-filter="updatePassword">修改密码</a></dd>
                        <dd><a lay-filter="logout">退出登陆</a></dd>
                    </dl>
                </li>
            </ul>
        </div>
        <div class="layui-side layui-bg-black" id="biz-side">
            <div class="layui-side-scroll ">
                <div class="biz-logo">
                    <span class="biz-logo-title">
                        {{d.title}}
                    </span>
                </div>

                {{# layui.each(d.menus, function(idx1, firstMenu){ }}
                {{# if(idx1 != 0){ }}
                <ul data-components="{{idx1}}" hidden class="layui-nav layui-nav-tree">
                    {{# }else{ }}
                    <ul data-components="{{idx1}}" class="layui-nav layui-nav-tree">
                        {{# } }}

                        {{# if(!firstMenu.children || !firstMenu.children.length){return;} }}
                        {{# layui.each(firstMenu.children,function(idx2, secondMenu){ }}
                        <li class="layui-nav-item">
                            <a class="{{secondMenu.icon}}" lay-filter="switchComponent" data-components="{{idx1}}"
                                data-component="{{idx2}}" data-url="{{secondMenu.url||''}}" href="javascript:;">
                                {{secondMenu.title}}
                            </a>

                            {{# if(!secondMenu.children || !secondMenu.children.length){return;} }}
                            <dl class="layui-nav-child">
                                {{#layui.each(secondMenu.children, function(idx3, threeMenu){ }}
                                <dd>
                                    <a data-url="{{threeMenu.url||''}}" lay-filter="openPage" href="javascript:;">
                                        <i class="{{threeMenu.icon}}"></i>
                                        {{threeMenu.title}}
                                    </a>
                                </dd>
                                {{# }); }}
                            </dl>
                        </li>
                        {{# }); }}

                    </ul>
                    {{# }); }}
                    <div id="biz-copyright">
                        {{d.copyright}}
                    </div>
            </div>
        </div>

        <div id="biz-body" class="layui-body">
            <div id="biz-tab" class="layui-tab layui-tab-card" lay-filter="bizTab" lay-allowClose="true"
                style="flex: 1;margin-bottom: 0;">
                <ul class="layui-tab-title" id="biz-tab-title">

                </ul>
                <div class="layui-tab-content" id="biz-tab-content">

                </div>
            </div>
        </div>
    </div>
</template>
<script type="text/html" id="updatePassword">
    <div class="layui-form" style="margin: 20px;">
        <div class="layui-form-item">
            <label class="layui-form-label">密码</label>
            <div class="layui-input-inline">
                <input type="password" name="password" required lay-verify="required" placeholder="请输入密码" autocomplete="off" class="layui-input">
            </div>
        </div>
        <div class="layui-form-item">
            <label class="layui-form-label">确认密码</label>
            <div class="layui-input-inline">
                <input type="password" name="confirm_password" required lay-verify="required" placeholder="请输入密码" autocomplete="off" class="layui-input">
            </div>
        </div>

    </div>
</script>
<script>
    layui.use(['app', 'api', 'jquery', 'dropdown', 'view', 'element', 'md5', 'api', 'func', 'authority'], function () {
        const { app, jquery: $, element, conf, view, dropdown, md5, api, func, authority } = layui;
        app({
            data: {
                side: {
                    show: true
                },
                copyright: "",
                menus: [],
                userNick: "",
                title: "",
            },
            beforeRender: async function () {
                const that = this;
                await Promise.all([
                    api("/system/menu/tree").then(({ data }) => {
                        that.menus = data;
                    }),
                    api("/system/user/info").then(function ({ data }) {
                        that.userNick = data.nick;
                        that.userAuths = data.auths;
                        //记录权限，后续展示需要使用

                        localStorage.setItem("user_auths", JSON.stringify(that.userAuths));
                    }),
                    api("/system/config/site").then(function ({ data }) {
                        that.copyright = data.copyright.replace('\\n', '<br>');
                        that.title = data.title;
                        document.title = that.title;
                    }),
                    authority.menus().then(function (menus) {
                        that.menus = menus;
                    }),
                ]);

                $(window).resize(function () {
                    that.resize();
                });

                window.layout = this;
            },
            afterRender: function () {
                element.on('tab(bizTab)', function (data) {
                    location.hash = $($("#biz-tab-title li")[data.index]).attr("lay-id");
                });


                $('[lay-filter="showSide"][data-show="1"]').hide();
                $('a:not([href])').attr('href', 'javascript:;');


                //构建菜单
                const that = this;
                //构建三级下拉菜单
                const dropdownMenus = [];
                this.menus.forEach(function (module) {
                    const dropDownModule = {
                        id: module.url,
                        title: module.title,
                        type: 'group',
                        isSpreadItem: false,
                        child: []
                    };
                    if(!$.isArray(module.children)){
                        return;
                    }
                    module.children.forEach(function (firstMenu) {
                        const dropDownFirstMenu = {
                            id: firstMenu.url,
                            title: firstMenu.title,
                            child: [],
                        };
                        if(!$.isArray(firstMenu.children)){
                            return;
                        }
                        firstMenu.children.forEach(function (secondMenu) {
                            dropDownFirstMenu.child.push({
                                id: secondMenu.url,
                                title: secondMenu.title,
                            });
                        });
                        dropDownModule.child.push(dropDownFirstMenu);
                    });
                    dropdownMenus.push(dropDownModule);
                });

                // dropdown.render({
                //     elem: '#biz-menu-dropdown' //可绑定在任意元素中，此处以上述按钮为例
                //     , data: dropdownMenus
                //     , id: 'demo1'
                //     //菜单被点击的事件
                //     , click: function (obj) {
                //         const tabFilter = 'bizTab';
                //         that.openTab(tabFilter, obj.title, obj.id);
                //     }
                // });

                //自动触发宽度适配
                this.resize();


                //打开默认页
                this.openTab(
                    '<i class="layui-icon layui-icon-home"></i>',
                    conf.view.entry,
                    "page"
                );


                //主动打开当前路由的页面
                $("[data-url='" + layui.router().href + "']").click();

                //默认选中第一个模块
                $("#biz-menu [data-index=0]").click();
                $("#biz-menu [data-index=0]").parent().addClass("layui-this");


                //自动打开地址页面
                var autoOpenPage = localStorage.getItem("auto_open_page");
                if (autoOpenPage) {
                    const that = this;
                    this.getMenuTitle(autoOpenPage, this.menus).then(function (title) {
                        that.openTab(title, autoOpenPage, "page");
                        localStorage.removeItem("auto_open_page");
                    });
                }
            },
            methods: {
                /**
                 * 打开新tab页
                 * @param title
                 * @param url
                 */
                openTab: function (title, url, type="page") {
                    var tabs = $("[lay-filter='bizTab'] [lay-id='" + url + "']");
                    if (tabs.length) {
                        //切到指定选项卡
                        element.tabChange('bizTab', url);
                        var iframeContent = $("#biz-body .layui-show > iframe");
                        if (iframeContent.length) {
                            iframeContent[0].contentWindow.location.reload();
                        }
                    } else {
                        //新建选项卡
                        element.tabAdd('bizTab', {
                            title: title,
                            content: '<iframe src="' + func.url(url) + '"></iframe>',
                            id: url
                        });

                        //切到指定选项卡
                        element.tabChange('bizTab', url);
                    }
                },
                /**
                 * 退出登录
                 */
                logout: function () {
                    layer.msg('正在退出登录');
                    api("/system/systemUser/logout").then(function () {
                        conf.api.token.remove();
                        view.route(conf.view.login);
                    });
                },
                /**
                 * 切换菜单
                 */
                switchModule: function (elem) {
                    const url = $(elem).data('url');
                    if (url) {
                        this.openTab($(elem).text(), url, $(elem).data("type"));
                        return;
                    }
                    const idx = $(elem).data('index');
                    $('ul[data-components]').hide();
                    $('ul[data-components="' + idx + '"]').show();
                },
                /**
                 * 选择组件（关闭相同树下其他组件）
                 */
                switchComponent: function (elem) {
                    const components = $(elem).data('component');
                    const component = $(elem).data('component');
                    $('a[data-component="' + components + '"]:not([data-component="' + component + '"])')
                        .parent().removeClass('layui-nav-itemed');

                    const url = $(elem).data('url');
                    const title = $(elem).text();

                    if (url) {
                        this.openTab(title, url, $(elem).data("type"));

                        setTimeout(function () {
                            $(elem).parent().removeClass("layui-this");
                        }, 500);
                    }
                },
                openPage: function (elem) {
                    const url = $(elem).data('url');
                    const title = $(elem).text();

                    if (!url) {
                        layer.msg(title + '未设置地址');
                        return;
                    }

                    this.openTab(title, url, $(elem).data("type"));

                    setTimeout(function () {
                        $(elem).parent().removeClass("layui-this");
                    }, 500);
                },
                /**
                 * 显示左侧导航栏
                 */
                showSide: function (elem) {
                    $(elem).hide();
                    const show = $(elem).data('show');
                    if (show) {
                        //显示
                        $('#biz-side').removeClass('biz-side-hide');
                        $('#biz-header').removeClass('biz-header-mobile');
                        $('#biz-tab-title').removeClass('biz-tab-title-mobile');
                        $('#biz-tab-content').removeClass('biz-tab-content-mobile');

                    } else {
                        //隐藏
                        $('#biz-side').addClass('biz-side-hide');
                        $('#biz-header').addClass('biz-header-mobile');
                        $('#biz-body').addClass('biz-body-mobile');
                        $('#biz-tab-title').addClass('biz-tab-title-mobile');
                        $('#biz-tab-content').addClass('biz-tab-content-mobile');
                    }

                    //显示另一个按钮
                    $('[lay-filter$="showSide"][data-show="' + (show ? 0 : 1) + '"]').show();

                },
                /**
                 * 切换主题
                 */
                updateTheme: function (elem) {
                    const theme = $(elem).data('theme');

                    if (conf.view.theme.curr === theme) {
                        layer.msg('当前已是该主题', { time: 30000 });
                        return;
                    }

                    layui.data('layout_theme', {
                        key: "curr",
                        value: theme,
                    });

                    layer.msg('切换主题，重新加载中。。。');
                    setTimeout(function () {
                        location.reload();
                    }, 1000);
                },
                /**
                 * 修改密码
                 */
                updatePassword: function () {
                    layer.open({
                        type: 1,
                        title: '修改密码',
                        content: $("#updatePassword").html(),
                        btn: ['确认', '取消'],
                        yes: function (index) {
                            const password = $('[name="password"]').val();
                            const confirm_password = $('[name="confirm_password"]').val();
                            if (!password) {
                                layer.msg("密码不能为空");
                                return;
                            }
                            if (password !== confirm_password) {
                                layer.msg("密码不一致");
                                return;
                            }
                            if (password.length < 6) {
                                layer.msg('密码长度必须大于6位');
                                return;
                            }
                            if (password.length > 15) {
                                layer.msg("密码长度必须小于15位");
                                return;
                            }
                            api("/system_user/SystemUser/updatePassword", {
                                old_password: oldPassword,
                                new_password: md5.exec(password),
                            }).then(function (res) {
                                layer.msg(res.msg);
                            })
                            layer.close(index);
                        },
                    });
                },
                /**
                 * 根据URL获取菜单标题
                 * @param currUrl
                 * @param node
                 */
                getMenuTitle: function (currUrl, root) {
                    return new Promise(function (resolve) {
                        var fn = function (node) {

                            if (!node) {
                                return;
                            }

                            if (node.url == currUrl) {
                                resolve(node.title);
                            }

                            if (!$.isArray(node.children)) {
                                return;
                            }

                            node.children.map(function (node) {
                                fn(node);
                            });
                        }

                        root.map(function (node) {
                            fn(node);
                        });
                    });
                },
                resize: function () {
                    const isMobile = document.body.clientWidth < 768;
                    //判断是手机还是电脑
                    if (isMobile) {
                        $('#biz-menu-dropdown').show();
                        $('#biz-side').addClass('biz-side-hide');
                        $('#biz-header').addClass('biz-header-mobile');
                        $('#biz-body').addClass('biz-body-mobile');
                        $('#biz-tab-title').addClass('biz-tab-title-mobile');
                        $('#biz-tab-content').addClass('biz-tab-content-mobile');
                        $('#biz-menu li:not(#biz-menu-dropdown)').hide();
                        // that.find('.layui-table-page .layui-laypage-limits').css('visibility', 'hide !important');
                        return;
                    } else {
                        $('#biz-menu-dropdown').hide();
                        $('#biz-side').removeClass('biz-side-hide');
                        $('#biz-header').removeClass('biz-header-mobile');
                        $('#biz-tab-title').removeClass('biz-tab-title-mobile');
                        $('#biz-tab-content').removeClass('biz-tab-content-mobile');
                        $('#biz-menu li:not(#biz-menu-dropdown)').show();
                        // that.find('.layui-table-page .layui-laypage-limits').css('visibility', 'visible  !important');
                        return;
                    }

                    var liArray = $('#menu-module').children('li').get();

                    var menuFold = $('#menu-fold')[0];
                    var menuOther = $('#menu-other')[0];

                    const lastLi = $('#menu-module li:visible').last()[0];

                    const distance = menuOther.offsetLeft - (lastLi.offsetLeft + lastLi.offsetWidth + menuFold.offsetWidth);

                    if (distance > 0) {
                        //判断最后一个的宽度是否能够显示，如果可以则显示，否则不操作
                        const li = liArray.filter(function (elem) {
                            if (elem.id === 'menu-fold') {
                                return false;
                            }

                            if (!$(elem).is(":hidden")) {
                                return false;
                            }

                            return true;
                        }).shift();
                        if (distance > $(li).width()) {
                            $(li).show();
                        }

                    } else {
                        const li = liArray.reverse().filter(function (elem) {
                            if (elem.id === 'menu-fold') {
                                return false;
                            }

                            if ($(elem).is(":hidden")) {
                                return false;
                            }

                            return true;
                        }).shift();

                        $(li).hide();
                    }

                    var hasItem = false;

                    //重置
                    $('#menu-fold .layui-nav-child a').each(function (idx, elem) {
                        const express = '#menu-module [lay-filter="switchModule"][data-index="' + $(elem).data('index') + '"]';
                        // console.log(express);
                        const method = $($(express)[0]).is(":hidden") ? "show" : 'hide';
                        $(elem).parent()[method]();
                        if (method === 'show') {
                            hasItem = true;
                        }

                    });
                    $('#menu-fold')[hasItem ? 'show' : 'hide']();

                },
            }
        })
    });
</script>